﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;

namespace ArrowScheduleCore
{
    /// <summary>
    /// Properties specific to a yearly schedule. Is either "run on MONTH, DAY" or "the WEEK WEEKDAY of MONTH." Run yearly
    /// always runs every year.
    /// </summary>
    public class ScheduleYearly : ScheduleMonth
    {

        /// <summary>
        /// The months of the year. These will always map to 1...13 where 13 is the 13th (extra) month that some calenders have.
        /// </summary>
        public enum MONTH
        {
            /// <summary>Run in January (day setting similiar to ScheduleMonthly).</summary>
            JANUARY = 1,
            /// <summary>Run in February (day setting similiar to ScheduleMonthly).</summary>
            FEBRUARY = 2,
            /// <summary>Run in March (day setting similiar to ScheduleMonthly).</summary>
            MARCH = 3,
            /// <summary>Run in April (day setting similiar to ScheduleMonthly).</summary>
            APRIL = 4,
            /// <summary>Run in May (day setting similiar to ScheduleMonthly).</summary>
            MAY = 5,
            /// <summary>Run in June (day setting similiar to ScheduleMonthly).</summary>
            JUNE = 6,
            /// <summary>Run in July (day setting similiar to ScheduleMonthly).</summary>
            JULY = 7,
            /// <summary>Run in August (day setting similiar to ScheduleMonthly).</summary>
            AUGUST = 8,
            /// <summary>Run in September (day setting similiar to ScheduleMonthly).</summary>
            SEPTEMBER = 9,
            /// <summary>Run in October (day setting similiar to ScheduleMonthly).</summary>
            OCTOBER = 10,
            /// <summary>Run in November (day setting similiar to ScheduleMonthly).</summary>
            NOVEMBER = 11,
            /// <summary>Run in December (day setting similiar to ScheduleMonthly).</summary>
            DECEMBER = 12,
            /// <summary>Run in the 13th month (day setting similiar to ScheduleMonthly).</summary>
            EXTRA = 13
        };

        private MONTH month;

        /// <summary>
        /// Create an object.
        /// </summary>
        /// <param name="cycle">Can be set to run on a specific day of the month or a specific week/weekday of the month.</param>
        /// <param name="day">The day of the month to run - DAY only.</param>
        /// <param name="month">The month to run in.</param>
        /// <param name="week">The week of the month to run in - MONTH only.</param>
        /// <param name="weekday">The weekday of the week to run in - MONTH only.</param>
        public ScheduleYearly(CYCLE cycle, int day, MONTH month, WEEK week, WEEKDAY weekday)
        {
            this.cycle = cycle;
            this.day = day;
            this.week = week;
            this.weekday = weekday;
            this.month = month;
        }

        /// <summary>
        /// Create an object for CYCLE.DAY.
        /// </summary>
        /// <param name="month">The month to run in.</param>
        /// <param name="day">The day of the month to run - DAY only.</param>
        public ScheduleYearly(MONTH month, int day)
        {
            cycle = CYCLE.DAY;
            this.day = day;
            this.month = month;
        }

        /// <summary>
        /// Create an object for CYCLE.WEEK.
        /// </summary>
        /// <param name="month">The month to run in.</param>
        /// <param name="week">The week of the month to run in.</param>
        /// <param name="weekday">The weekday of the week to run in.</param>
        public ScheduleYearly(MONTH month, WEEK week, WEEKDAY weekday)
        {
            cycle = CYCLE.WEEK;
            this.week = week;
            this.weekday = weekday;
            this.month = month;
        }

        /// <summary>
        /// The month to run in.
        /// </summary>
        public MONTH Month
        {
            get { return month; }
            set { month = value; }
        }

        /// <summary>
        /// Use this instead of class type only when necessary such as a switch statement.
        /// </summary>
        public override REPEAT RepeatType
        {
            get { return REPEAT.YEARLY; }
        }
        /// <summary>
        /// A human readable description of the period.
        /// </summary>
        public override string Description
        {
            get
            {
                DateTimeFormatInfo info = CultureInfo.CurrentUICulture.DateTimeFormat;

                if (cycle == CYCLE.DAY)
                    return String.Format(GlobalStrings.ScheduleYearly_schdYearDay, info.GetMonthName((int)month), day);
                return String.Format(GlobalStrings.ScheduleYearly_schdYearWeekDay, info.GetMonthName((int)month), WeekAsString, WeekdayAsString);
            }
        }
    }
}
